#pragma once

#include "Layer.h"
#include <MyFC/GridControl.h>
#include <MyFC/Glyph.h>
#include "TreeControl.h"
#include "DLL.h"

namespace My {

class LayerRow;
class Timeline;
class Xline;

class DLL_API LayerControl : public Container
{
	class Control : public My::Control
	{
	protected:
		LayerControl &	m_LayerControl;
		Timeline &		m_Timeline;
	public:
		Control(LayerControl &);
		virtual bool Visible() const;
		virtual void HandleLeftDown(unsigned int, const CPoint &);
	};

	class LeftBracket : public Control
	{
	private:
		int		m_StartPos;
		int		m_StartValue;
	public:
		LeftBracket(LayerControl & c) : Control(c) { }
	public:
		virtual CRect Bounds() const;
		virtual String Hint() const 
			{ return "Trimming"; }
		virtual bool HandleDragStart(unsigned int flags, const CPoint & p0, const CPoint & p);
		virtual void HandleDragEnd(unsigned int flags, const CPoint & p);
		virtual void HandleDragging(unsigned int flags, const CPoint & p);
	};

	class RightBracket : public Control
	{
	private:
		int		m_StartPos;
		int		m_StartValue;
	public:
		RightBracket(LayerControl & c) : Control(c) { }
	public:
		virtual CRect Bounds() const;
		virtual String Hint() const 
			{ return "Trimming"; }
		virtual bool HandleDragStart(unsigned int flags, const CPoint & p0, const CPoint & p);
		virtual void HandleDragEnd(unsigned int flags, const CPoint & p);
		virtual void HandleDragging(unsigned int flags, const CPoint & p);
	};

public:
	virtual CRect Bounds() const;
public:
	LayerControl(LayerRow &);
	~LayerControl();
	Layer * GetLayer() const
		{ return m_pLayer; }
	void SetLayer(Layer *);
public:
	bool IsEmpty() const;
	int GetSourceOffset() const;
	Span GetSourceSpan() const;
	void SetSourceOffset(int time);
	void UpdateSourceOffset();
	Span GetTrimming() const;
	Span GetAbsoluteTrimming() const;
	void SetTrimming(Span s);
	void UpdateTrimming();
public:
	virtual bool HandleDragStart(unsigned int flags, const CPoint & p0, const CPoint & p);
	virtual void HandleDragEnd(unsigned int flags, const CPoint & p);
	virtual void HandleDragging(unsigned int flags, const CPoint & p);
	virtual void HandleLeftDown(unsigned int flags, const CPoint & p);
	virtual void HandlePaint(CDC * pDC, const CRect & r);
	virtual void ProcessEvent(Event &);
private:
	LayerRow &		m_LayerRow;
	Timeline &		m_Timeline;
	Layer *			m_pLayer;
	LeftBracket		m_LeftBracket;
	RightBracket	m_RightBracket;
	int				m_SourceOffset;
	Span			m_Trimming;
	int				m_StartPos;
	int				m_StartValue;
	bool			m_DragTrimming;
	Span			m_StartTrimming;
public:
	My::SysColorGlyph		m_LeftGlyph;
	My::SysColorGlyph		m_RightGlyph;
	CBitmap					m_LightGreenRipple;
	CBitmap					m_DarkGreenRipple;
};

class DLL_API LayerRow : 
	public GridRow,
	public virtual TreeRow
{
	friend class LayerControl;
public:
	LayerRow(Xline &, const String & caption);
	~LayerRow();
public:
	bool IsEmpty() const;
	Layer * GetLayer() const
		{ return m_pLayer; }
	Xline & GetXline() const
		{ return m_Xline; }
	void SetLayer(Layer *);
public:
	virtual String GetCaption() const
		{ return m_Caption; }
	virtual void HandlePaint(CDC *, const CRect &);
	virtual void HandleLeftDown(unsigned int, const CPoint &);
	virtual void PaintCell(CDC *, const CRect & rClip, const Column &, const CRect & rCell);
	virtual void ProcessEvent(Event &);
private:
	Xline &			m_Xline;
	String			m_Caption;
	Layer *			m_pLayer;
	LayerControl	m_Control;
};

} // My